﻿using Kingdee.BOS.Core.List;
using Kingdee.BOS.Core.List.PlugIn;
using Kingdee.BOS.Util;
using Kingdee.BOS;
using System.ComponentModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.Core.DynamicForm;
using System.Threading.Tasks;
using Kingdee.BOS.Contracts;
using Kingdee.BOS.App;
using Kingdee.BOS.Core.Metadata.ConvertElement.ServiceArgs;
using Kingdee.BOS.Core.DynamicForm.Operation;
using Kingdee.BOS.Orm;
using Kingdee.BOS.Core.Interaction;
using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.Core.Bill;
using Kingdee.BOS.Core.Permission;
using Kingdee.BOS.Core.Metadata.EntityElement;
using Kingdee.BOS.App.Core.Warn.Data;
using Kingdee.BOS.Core.DynamicForm.PlugIn;
using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;
using Kingdee.BOS.App.Data;

namespace XiaTuiXiaoShouDingDan
{

    [Description("销售报价单单据按钮点击直接下推销售订单")]
    [HotUpdate]
    public class XiaTuiXiaoShouDingDan : AbstractDynamicFormPlugIn
    {

        public override void BarItemClick(Kingdee.BOS.Core.DynamicForm.PlugIn.Args.BarItemClickEventArgs e)
        {

            if (e.BarItemKey.Equals("VHTP_tbButton_2") || e.BarItemKey.Equals("VHTP_tbButton_3"))
            {
                this.View.ShowMessage("是否下推销售订单？",
                 //提示信息：是、否
                 MessageBoxOptions.YesNo,
                 new Action<MessageBoxResult>((result) =>
                 {
                     if (result == MessageBoxResult.Yes)
                     {   // 单据编号 绑定实体属性 BillNo
                         string FBillNo = this.View.Model.GetValue("FBillNo").ToString(); ;//编号
                         string sql = "select FID from T_SAL_QUOTATION where FBILLNO='" + FBillNo + "' ";
                         DataTable dt;
                         dt = DBUtils.ExecuteDataSet(this.Context, sql).Tables[0];
                         for (int i = 0; i < dt.Rows.Count; i++)
                         {
                             ListSelectedRow row = new ListSelectedRow(dt.Rows[i]["FID"].ToString(), string.Empty, 0, "SAL_QUOTATION");
                             ListSelectedRow[] selectedRows = new ListSelectedRow[] { row };
                             //销售报价单（一级报价单）唯一标识：888f3744-98dc-4b53-b0e5-a1b515d4d57c   ||    SAL_QUOTATION
                             //销售订单唯一标识：SAL_SaleOrder
                             //this.DoPush("SAL_QUOTATION", "kec08182a397043bbbf5ffe32315c66d5", selectedRows);
                             this.DoPush("SAL_QUOTATION", "SAL_SaleOrder", selectedRows);
                             this.View.ShowMessage("下推销售订单成功");
                         }
                         //如果选择的是,给备注赋值,是
                         this.View.Model.SetValue("FNote", "下推");

                     }
                     else if (result == MessageBoxResult.No)
                     {
                         //如果选择的否,给备注赋值,否
                         this.View.Model.SetValue("FNote", "取消");
                     }
                 }));
                this.View.UpdateView("FNote");




            }


        }

        private void DoPush(string sourceFormId, string targetFormId, ListSelectedRow[] selectedRows)
        {
            // 获取源单与目标单的转换规则
            IConvertService convertService = ServiceHelper.GetService<IConvertService>();
            var rules = convertService.GetConvertRules(this.Context, sourceFormId, targetFormId);


            if (rules == null || rules.Count == 0)
            {
                throw new KDBusinessException("", string.Format("未找到销售报价单到销售订单，启用的转换规则，无法自动下推！", sourceFormId, targetFormId));
            }
            // 取勾选了默认选项的规则
            var rule = rules.FirstOrDefault(t => t.IsDefault);
            // 如果无默认规则，则取第一个
            if (rule == null)
            {
                rule = rules[0];
            }

            /* // 开始构建下推参数：
             // 待下推的源单数据行
             List srcSelectedRows = new List();

             foreach (var billId in sourceBillIds)
             {// 把待下推的源单内码，逐个创建ListSelectedRow对象，添加到集合中
              //srcSelectedRows.Add(new ListSelectedRow(billId.ToString(), string.Empty, 0, sourceFormId));
              // 特别说明：上述代码，是整单下推；
              // 如果需要指定待下推的单据体行，请参照下句代码，在ListSelectedRow中，指定EntryEntityKey以及EntryId
                 srcSelectedRows.Add(new ListSelectedRow(billId.fid.ToString(), billId.fentryid.ToString(), 0, sourceFormId) { EntryEntityKey = "FEntity" });

             }*/

            // 指定目标单单据类型:情况比较复杂，没有合适的案例做参照，示例代码暂略，直接留空，会下推到默认的单据类型
            string targetBillTypeId = string.Empty;
            // 指定目标单据主业务组织：情况更加复杂，需要涉及到业务委托关系，缺少合适案例，示例代码暂略
            // 建议在转换规则中，配置好主业务组织字段的映射关系：运行时，由系统根据映射关系，自动从上游单据取主业务组织，避免由插件指定
            long targetOrgId = 0;
            // 自定义参数字典：把一些自定义参数，传递到转换插件中；转换插件再根据这些参数，进行特定处理
            Dictionary<string, object> custParams = new Dictionary<string, object>();
            // 组装下推参数对象
            PushArgs pushArgs = new PushArgs(rule, selectedRows)
            {

                TargetBillTypeId = targetBillTypeId,
                TargetOrgId = targetOrgId,
                CustomParams = custParams

            };

            // 调用下推服务，生成下游单据数据包
            ConvertOperationResult operationResult = convertService.Push(this.Context, pushArgs, OperateOption.Create());
            // 开始处理下推结果:
            // 获取下推生成的下游单据数据包
            DynamicObject[] targetBillObjs = (from p in operationResult.TargetDataEntities select p.DataEntity).ToArray();
            if (targetBillObjs.Length == 0)
            {
                // 未下推成功目标单，抛出错误，中断审核
                throw new KDBusinessException("", string.Format("由{0}自动下推{1}，没有成功生成数据包，自动下推失败！", sourceFormId, targetFormId));
            }

            // 对下游单据数据包，进行适当的修订，以避免关键字段为空，自动保存失败
            // 示例代码略

            // 获取生成的目标单据数据包
            DynamicObject[] objs = (from p in operationResult.TargetDataEntities
                                    select p.DataEntity).ToArray();
            //MustQty RealQty Lot批号 BaseUnitQty基本单位数量
            // ((DynamicObject)((DynamicObjectCollection)((DynamicObject)objs[0])[66])[0])[8] = WeightPlan;
            /*int i = 0;
            foreach (var billId in sourceBillIds)
            {
                ((DynamicObject)((DynamicObjectCollection)((DynamicObject)objs[0])["SAL_OUTSTOCKENTRY"])[i])["RealQty"] = Convert.ToInt32(billId.FQTYRETURNEDGOODSWRITTENOFF2);
                ((DynamicObject)((DynamicObjectCollection)((DynamicObject)objs[0])["SAL_OUTSTOCKENTRY"])[i])["alreadyQty"] = Convert.ToInt32(billId.FQTYRETURNEDGOODSWRITTENOFF2);
                ((DynamicObject)((DynamicObjectCollection)((DynamicObject)objs[0])["SAL_OUTSTOCKENTRY"])[i])["WaitingQty"] = 0;
                (((DynamicObject)objs[0])["FOUTSTOCKTYPE"]) = Convert.ToString(billId.FBUSINESSTYPES2);
                if (billId.FEXCHANGERATE > 0)
                {
                    ((DynamicObject)((DynamicObjectCollection)((DynamicObject)objs[0])["SAL_OUTSTOCKFIN"])[0])["ExchangeRate"] = Convert.ToInt32(billId.FEXCHANGERATE);
                }
                else
                {

                    ((DynamicObject)((DynamicObjectCollection)((DynamicObject)objs[0])["SAL_OUTSTOCKFIN"])[0])["ExchangeRate"] = 1.0;
                }

                i++;

            }
*/
            // 读取目标单据元数据
            IMetaDataService metaService = ServiceHelper.GetService<IMetaDataService>();
            var targetBillMeta = metaService.Load(this.Context, targetFormId) as FormMetadata;

            // 构建保存操作参数：设置操作选项值，忽略交互提示
            OperateOption saveOption = OperateOption.Create();

            // 忽略全部需要交互性质的提示，直接保存；
            saveOption.SetIgnoreWarning(true); // 忽略交互提示
            /* saveOption.SetInteractionFlag(this.Option.GetInteractionFlag()); // 如果有交互，传入用户选择的交互结果
                                                                              // using Kingdee.BOS.Core.Interaction;
             saveOption.SetIgnoreInteractionFlag(this.Option.GetIgnoreInteractionFlag());*/
            //// 如下代码，强制要求忽略交互提示(演示案例不需要，注释掉)
            //saveOption.SetIgnoreWarning(true);
            //// using Kingdee.BOS.Core.Interaction;
            //saveOption.SetIgnoreInteractionFlag(true);

            // 调用保存服务，自动保存
            ISaveService saveService = ServiceHelper.GetService<ISaveService>();
            var saveResult = saveService.Save(this.Context, targetBillMeta.BusinessInfo, targetBillObjs, saveOption, "Save");
            // 判断自动保存结果：只有操作成功，才会继续
            if (this.CheckOpResult(saveResult, saveOption))
            {
                return;
            }
        }

        /// 判断操作结果是否成功，如果不成功，则直接抛错中断进程
        /// 
        /// 操作结果
        /// 操作参数
        /// 
        /// 
        private bool CheckOpResult(IOperationResult opResult, OperateOption opOption)
        {
            bool isSuccess = false;
            if (opResult.IsSuccess == true)
            {
                // 操作成功
                isSuccess = true;
            }
            else
            {
                if (opResult.InteractionContext != null && opResult.InteractionContext.Option.GetInteractionFlag().Count > 0)
                {
                    /* // 有交互性提示
                     // 传出交互提示完整信息对象
                     this.OperationResult.InteractionContext = opResult.InteractionContext;
                     // 传出本次交互的标识，
                     // 用户在确认继续后，会重新进入操作；
                     // 将以此标识取本交互是否已经确认过，避免重复交互
                     this.OperationResult.Sponsor = opResult.Sponsor;*/
                    // 抛出交互错误，把交互信息传递给前端
                    new KDInteractionException(opOption, opResult.Sponsor);

                }
                else
                {
                    // 操作失败，拼接失败原因，然后抛出中断
                    opResult.MergeValidateErrors();
                    if (opResult.OperateResult == null)
                    {// 未知原因导致提交失败
                        throw new KDBusinessException("", "未知原因导致自动提交、审核失败！");
                    }
                    else
                    {

                        StringBuilder sb = new StringBuilder();
                        sb.AppendLine("自动操作失败：");
                        foreach (var operateResult in opResult.OperateResult)
                        {
                            sb.AppendLine(operateResult.Message);
                        }
                        throw new KDBusinessException("", sb.ToString());
                    }
                }
            }
            return isSuccess;
        }
    }
}
